﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace Demo.Mmose.Core.Common.Atom
{

    /// <summary>
    /// BaseCharacter的事件数据类
    /// </summary>
    public class UpdatingValue<ValueTypeT> : EventArgs
    {
        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 初始化构造
        /// </summary>
        /// <param AccessLevel="baseCharacter"></param>
        public UpdatingValue( ValueTypeT value )
        {
            m_Value = value;
        }
        #endregion

        #region zh-CHS 共有属性 | en Public Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private ValueTypeT m_Value;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public ValueTypeT Value
        {
            get { return m_Value; }
        }

        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private bool m_IsCancel = false;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public bool IsCancel
        {
            get { return m_IsCancel; }
            set { m_IsCancel = value; }
        }
        #endregion
    }

    /// <summary>
    /// BaseCharacter的事件数据类
    /// </summary>
    public class UpdatedValue<ValueTypeT> : EventArgs
    {
        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 初始化构造
        /// </summary>
        /// <param AccessLevel="baseCharacter"></param>
        public UpdatedValue( ValueTypeT value )
        {
            m_Value = value;
        }
        #endregion

        #region zh-CHS 共有属性 | en Public Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private ValueTypeT m_Value;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public ValueTypeT Value
        {
            get { return m_Value; }
        }
        #endregion
    }

    //Atomic Reference Struct

    public interface IAtomOperator<ValueTypeT>
    {
        /// <summary>
        /// 
        /// </summary>
        ValueTypeT Value { get; }

        /// <summary>
        /// 以原子方式将给定值与当前值相加。
        /// </summary>
        /// <param name="addValue"></param>
        /// <returns></returns>
        void Add( ValueTypeT addValue );
        /// <summary>
        /// 以原子方式将给定值与当前值相减。
        /// </summary>
        /// <param name="subtractValue"></param>
        /// <returns></returns>
        void Subtract( ValueTypeT subtractValue );
        /// <summary>
        /// 以原子方式将给定值与当前值相乘。
        /// </summary>
        /// <param name="multiplyValue"></param>
        /// <returns></returns>
        void Multiply( ValueTypeT multiplyValue );
        /// <summary>
        /// 以原子方式将给定值与当前值相除。
        /// </summary>
        /// <param name="divideValue"></param>
        /// <returns></returns>
        void Divide( ValueTypeT divideValue );
        /// <summary>
        /// 以原子方式设置为给定值。
        /// </summary>
        /// <param name="assignmentValue"></param>
        /// <returns></returns>
        void Assignment( ValueTypeT assignmentValue );
        /// <summary>
        /// 如果当前值 == 预期值，则以原子方式将该值设置为给定的更新值。
        /// </summary>
        /// <param name="setValue"></param>
        /// <param name="compareValue"></param>
        /// <returns></returns>
        bool CompareExchange( ValueTypeT setValue, ValueTypeT compareValue );
        /// <summary>
        /// 以原子方式将当前值减 1 ( -- )
        /// </summary>
        /// <returns></returns>
        void Decrement();
        /// <summary>
        /// 以原子方式将当前值加 1 ( ++ )
        /// </summary>
        /// <returns></returns>
        void Increment();
        /// <summary>
        /// 以原子方式将当前值左移 ( << )
        /// </summary>
        /// <returns></returns>
        void LeftShift( int leftShift );
        /// <summary>
        /// 以原子方式将当前值右移 ( >> )
        /// </summary>
        /// <returns></returns>
        void RightShift( int rightShift );
        /// <summary>
        /// 以原子方式将当前值求正(一元操作) ( + )
        /// </summary>
        void Plus();
        /// <summary>
        /// 以原子方式将当前值求负(一元操作) ( - )
        /// </summary>
        void Minus();
        /// <summary>
        /// 以原子方式将当前值取反(一元操作) ( ! )
        /// </summary>
        void Invert();
        /// <summary>
        /// 以原子方式将当前值求补 ( ~ )
        /// </summary>
        /// <returns></returns>
        void OneComplement();
        /// <summary>
        /// 以原子方式将当前值按位与 ( &= )
        /// </summary>
        /// <returns></returns>
        void BitwiseAND( ValueTypeT bitwiseAnd );
        /// <summary>
        /// 以原子方式将当前值按位或 ( |= )
        /// </summary>
        /// <returns></returns>
        void BitwiseInclusiveOR( ValueTypeT inclusiveOR );
        /// <summary>
        /// 以原子方式将当前值按位异或 ( ^= )
        /// </summary>
        /// <returns></returns>
        void BitwiseExclusiveOR( ValueTypeT exclusiveOR );

        event EventHandler<UpdatingValue<ValueTypeT>> UpdatingValue;
        event EventHandler<UpdatedValue<ValueTypeT>> UpdatedValue;
    }

    public class AtomOperator<ValueT> where ValueT : struct
    {
        #region zh-CHS 构造和初始化和清理 | en Constructors and Initializers and Dispose
        /// <summary>
        /// 
        /// </summary>
        public AtomOperator()
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="atomicInt"></param>
        public AtomOperator( ValueT atomOperator )
        {
            m_AtomicOperator = atomOperator;
        }
        #endregion

        #region zh-CHS 属性 | en Properties
        #region zh-CHS 私有成员变量 | en Private Member Variables
        /// <summary>
        /// 
        /// </summary>
        private ValueT m_AtomicOperator;
        #endregion
        /// <summary>
        /// 
        /// </summary>
        public ValueT Value
        {
            get { return m_AtomicOperator; }
        }
        #endregion

        #region zh-CHS 方法 | en Method
        /// <summary>
        /// 
        /// </summary>
        /// <param name="iAdd"></param>
        //public KeyT Add( KeyT iAddValue )
        //{
        //    return Interlocked.Add( ref m_AtomicInt, iAddValue );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iAdd"></param>
        //public KeyT Set( KeyT iSetValue )
        //{
        //    return Interlocked.Exchange( ref m_AtomicInt, iSetValue );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iValue"></param>
        /// <param name="iCompare"></param>
        //public int CompareExchange( KeyT iSetValue, KeyT iCompareValue )
        //{
        //    return Interlocked.CompareExchange( ref m_AtomicInt, iSetValue, iCompareValue );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator ==( AtomicInt atomicIntA, AtomicInt atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) == Thread.VolatileRead( ref atomicIntB.m_AtomicInt );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator ==( AtomicInt atomicIntA, int atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) == atomicIntB;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator !=( AtomicInt atomicIntA, AtomicInt atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) != Thread.VolatileRead( ref atomicIntB.m_AtomicInt );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator !=( AtomicInt atomicIntA, int atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) != atomicIntB;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator <( AtomicInt atomicIntA, AtomicInt atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) < Thread.VolatileRead( ref atomicIntB.m_AtomicInt );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator <( AtomicInt atomicIntA, int atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) < atomicIntB;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator >( AtomicInt atomicIntA, AtomicInt atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) > Thread.VolatileRead( ref atomicIntB.m_AtomicInt );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator >( AtomicInt atomicIntA, int atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) > atomicIntB;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator <=( AtomicInt atomicIntA, AtomicInt atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) <= Thread.VolatileRead( ref atomicIntB.m_AtomicInt );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator <=( AtomicInt atomicIntA, int atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) <= atomicIntB;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator >=( AtomicInt atomicIntA, AtomicInt atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) >= Thread.VolatileRead( ref atomicIntB.m_AtomicInt );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static bool operator >=( AtomicInt atomicIntA, int atomicIntB )
        //{
        //    return Thread.VolatileRead( ref atomicIntA.m_AtomicInt ) >= atomicIntB;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static AtomicInt operator ++( AtomicInt atomicInt )
        //{
        //    Interlocked.Increment( ref atomicInt.m_AtomicInt );
        //    return atomicInt;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="l"></param>
        /// <param name="r"></param>
        /// <returns></returns>
        //public static AtomicInt operator --( AtomicInt atomicInt )
        //{
        //    Interlocked.Decrement( ref atomicInt.m_AtomicInt );
        //    return atomicInt;
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iSerial"></param>
        /// <returns></returns>
        //public static explicit operator int( AtomicInt atomicInt )
        //{
        //    return Thread.VolatileRead( ref atomicInt.m_AtomicInt );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="iAtomicInt"></param>
        /// <returns></returns>
        //public static implicit operator AtomicInt( int iAtomicInt )
        //{
        //    return new AtomicInt( iAtomicInt );
        //}
        #endregion

        #region zh-CHS 方法覆盖 | en Method Overrides
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            return String.Format( "0x{0:X8}", m_AtomicOperator );
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public override int GetHashCode()
        {
            return m_AtomicOperator.GetHashCode();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="xObject"></param>
        /// <returns></returns>
        //public override bool Equals( object xObject )
        //{
        //    AtomOperator<KeyT> atomicInt = xObject as AtomOperator<KeyT>;
        //    if ( atomicInt == null )
        //        return false;

        //    return atomicInt.m_AtomicInt == m_AtomicInt;
        //}
        #endregion

        #region zh-CHS 接口实现 | en Interface Implementation
        /// <summary>
        /// 
        /// </summary>
        /// <param name="otherAtomicInt"></param>
        /// <returns></returns>
        //public int CompareTo( AtomOperator<KeyT> otherAtomicInt )
        //{
        //    return m_AtomicInt.CompareTo( otherAtomicInt.m_AtomicInt );
        //}

        /// <summary>
        /// 
        /// </summary>
        /// <param name="otherObject"></param>
        /// <returns></returns>
        public int CompareTo( object otherObject )
        {
            AtomOperator<ValueT> atomicInt = otherObject as AtomOperator<ValueT>;
            if ( atomicInt == null )
                return 1;
            else
                return CompareTo( atomicInt );
        }
        #endregion
    }
}
